package com.qingcheng.timer;

import com.qingcheng.dao.SeckillGoodsMapper;
import com.qingcheng.dao.SeckillOrderMapper;
import com.qingcheng.pojo.seckill.SeckillGoods;
import com.qingcheng.pojo.seckill.SeckillOrder;
import com.qingcheng.service.seckill.SeckillOrderService;
import com.qingcheng.util.IdWorker;
import com.qingcheng.util.SeckillStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.logging.SimpleFormatter;

/**
 * @Author:boy
 * @Date:2019/7/24
 * @description:
 * @ModifiedBy:
 */
@Component
public class MultiThreadingCreateOrder {
    @Autowired
    private SeckillOrderMapper seckillOrderMapper;
    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private SeckillOrderService seckillOrderService;
    private Logger logger = LoggerFactory.getLogger(MultiThreadingCreateOrder.class);

    @Async
    public void createOrder() {
        //从订单队列中弹出
        SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundListOps("SeckillOrderQueue").rightPop();
        try {
            if (seckillStatus != null) {
                seckillOrderService.sendDelayMessage(seckillStatus);
                //从redis中取出库存数
                Object sgood = redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillStatus.getGoodsId()).rightPop();
                if (sgood == null) {
                    //已卖完，清理当前排队信息
                    this.cleanQueue(seckillStatus);
                    return;
                }
                logger.info("[" + LocalDate.now() + "]", "开始异步添加订单");
                //时间区间
                String time = seckillStatus.getTime();
                //用户名
                String username = seckillStatus.getUsername();
                //id
                Long id = seckillStatus.getGoodsId();
                //从缓存中取出商品数据
                SeckillGoods goods = (SeckillGoods) redisTemplate.boundHashOps("SeckillGoods_" + time).get(id);
                if (goods == null || goods.getStockCount() <= 0) {//商品已售完
                    seckillStatus.setStatus(4);
                    redisTemplate.boundHashOps("UserQueueStatus").put(username, seckillStatus);
                    throw new RuntimeException("已售完");
                }
                //商品未售完
                SeckillOrder order = new SeckillOrder();
                order.setId(idWorker.nextId());
                order.setSeckillId(id);
                order.setMoney(goods.getCostPrice());
                order.setUserId(username);
                order.setSellerId(goods.getSellerId());
                order.setCreateTime(new Date());
                order.setStatus("0");
                //秒杀订单存入redis中
                redisTemplate.boundHashOps("SeckillOrder").put(username, order);
                //减少商品库存
                Long surPlusCount = redisTemplate.boundHashOps("SeckGoodsCount").increment(id, -1);
                //重新设置库存
                goods.setStockCount(surPlusCount.intValue());
                if (goods.getStockCount() <= 0) {//没有库存
                    //商品数据同步到mysql
                    seckillGoodsMapper.updateByPrimaryKeySelective(goods);
                    //清空缓存中的数据
                    redisTemplate.boundHashOps("SeckillGoods_" + time).delete(id);
                } else {
                    //如果有库存
                    redisTemplate.boundHashOps("SeckillGoods_" + time).put(id, goods);
                }
                //抢单成功 更改抢单状态  等待支付
                seckillStatus.setStatus(2);
                seckillStatus.setOrderId(order.getId());
                seckillStatus.setMoney(order.getMoney().floatValue());
                redisTemplate.boundHashOps("UserQueueStatus").put(username, seckillStatus);
                //打印日志
                logger.info("[" + LocalDate.now() + "]", "添加订单结束");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void cleanQueue(SeckillStatus seckillStatus) {
        //清理排队标识
        redisTemplate.boundHashOps("UserQueueCount").delete(seckillStatus.getUsername());
        //清理抢单标识
        redisTemplate.boundHashOps("UserQueueStatus").delete(seckillStatus.getUsername());
    }
}
